// testView.cpp : implementation of the CTestView class
//

#include "stdafx.h"
#include "test.h"
#include "math.h"

#include "testDoc.h"
#include "testView.h"
#include "CFill.h"
#include "QFill.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#define Round(d) int (floor(d+0.5))
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTestView

IMPLEMENT_DYNCREATE(CTestView, CView)

BEGIN_MESSAGE_MAP(CTestView, CView)
	//{{AFX_MSG_MAP(CTestView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestView construction/destruction

CTestView::CTestView()
{
	// TODO: add construction code here

}

CTestView::~CTestView()
{
}

BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CTestView drawing

void CTestView::OnDraw(CDC* pDC)
{	
	CTestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	/*更改坐标系为数学坐标系*/
	CRect rect;
	GetClientRect(&rect);
	//设置映射模式
	pDC->SetMapMode(8);
	//设置窗口大小
	pDC->SetWindowExt(rect.Width(),rect.Height());
	//设置视图大小
	pDC->SetViewportExt(rect.Width(), -rect.Height());
	//设置坐标轴原点
	pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
	//客户区矫正
	rect.OffsetRect(-rect.Width()/2, -rect.Height()/2);

	CPen *pOldPen;
	CBrush *pOldBrush;

    
	//耳朵（左耳 圆角矩形）
	CPen Pen2;
	Pen2.CreatePen(PS_SOLID,5,RGB(209,96,100));
	CBrush bursh2;
	bursh2.CreateSolidBrush(RGB(255,82,82));
	pOldBrush =  pDC->SelectObject(&bursh2);
	pOldPen = pDC->SelectObject(&Pen2);
	CPoint lear[2],whpoint3(20,20); 
	lear[0].x = -120; lear[0].y = 70;
	lear[1].x = -90; lear[1].y = -55;
	CRect rect5(lear[0],lear[1]);
	pDC->RoundRect(rect5,whpoint3);

	//耳朵（右耳 圆角矩形） [与左耳对称]
	CPoint rear[2],whpoint4(20,20); 
	rear[0].x = -lear[0].x; rear[0].y = lear[0].y;
	rear[1].x = -lear[1].x; rear[1].y = lear[1].y;
	CRect rect6(rear[0],rear[1]);
	pDC->RoundRect(rect6,whpoint4);
	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);

	//头（圆角方形）
	CPen Pen1;
	Pen1.CreatePen(PS_SOLID,5,RGB(101,140,161));
	CBrush bursh1;
	bursh1.CreateSolidBrush(RGB(136,164,177));
	pOldBrush =  pDC->SelectObject(&bursh1);
	pOldPen = pDC->SelectObject(&Pen1);
	CPoint head[2],whpoint(20,20); 
	head[0].x = -100; head[0].y = 90;
	head[1].x = 100; head[1].y = -75;
	CRect rect1(head[0],head[1]);
	pDC->RoundRect(rect1,whpoint);
	pDC->SelectObject(pOldBrush);

	//天线 部件1（直线）

	//准备一只无色笔
	
	pDC->MoveTo(0,90);
	pDC->LineTo(0,120);

	


	//天线 部件2（圆形）
	CPoint slel[2];
	slel[0].x = -20; slel[0].y = 160;
	slel[1].x = 20; slel[1].y = 120;
	CRect rect7(slel[0],slel[1]);
	pDC->Ellipse(rect7);

	//天线 部件3（内圆）
	pOldBrush =  pDC->SelectObject(&bursh2);
	CPoint slel_inside[2];
	slel_inside[0].x = -15; slel_inside[0].y = 155;
	slel_inside[1].x = 15; slel_inside[1].y = 125;
	CRect rect8(slel_inside[0],slel_inside[1]);
	pDC->Ellipse(rect8);
	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);

	
	

	//眼睛（左眼 圆形）
	CPen Pen0;
	Pen0.CreatePen(PS_SOLID,5,RGB(104,104,104));
	pOldPen = pDC->SelectObject(&Pen0);
	CPoint leye[2];
	leye[0].x = -60; leye[0].y = 65;
	leye[1].x = -15; leye[1].y = 20;
	CRect rect2(leye[0],leye[1]);
	pDC->Ellipse(rect2);
	

	//眼睛（右眼 圆形）[与左眼对称]
	CPoint reye[2];
	reye[0].x = -leye[1].x; reye[0].y = leye[1].y;
	reye[1].x = -leye[0].x; reye[1].y = leye[0].y;
	CRect rect3(reye[0],reye[1]);
	pDC->Ellipse(rect3);


	//嘴巴（圆角方形）
	CPoint mouth[2],whpoint2(35,35); 
	mouth[0].x = -50; mouth[0].y = -25;
	mouth[1].x = 50; mouth[1].y = -50;
	CRect rect4(mouth[0],mouth[1]);

	pDC->RoundRect(rect4,whpoint2);

	pDC->SelectObject(pOldPen);

	//鼻子
	pOldPen = pDC->SelectObject(&Pen2);
	CPoint nose[3];
	nose[0].x =0; nose[0].y =25; 
	nose[1].x=-20; nose[1].y =-10;
	nose[2].x =20; nose[2].y =-10;
	QFill *noseqf = new QFill();
	noseqf->DrawPolygon(pDC,nose,3);
	pDC->SelectObject(pOldPen);
	CPoint seed(0, 0);
	COLORREF SeedClr = RGB(255,82,82);
	COLORREF BoundaryClr = RGB(209,96,100);


	//文字
	//产生字体
	CFont font;
	font.CreateFont(100, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY, VARIABLE_PITCH|FF_ROMAN, "Times New Roman");
	//将字体选进DC中
	CFont* pOldFont = pDC->SelectObject(&font);
	COLORREF textColor = RGB(255,82,82);
	pDC->SetTextColor(textColor);
	pDC->TextOut(-220,300,"锤子指路牌");
	//释放字体
	pDC->SelectObject(pOldFont);


	//牙齿（直线）
	pDC->MoveTo(-29,-25);
	pDC->LineTo(-30,-50);
	pDC->MoveTo(31,-25);
	pDC->LineTo(30,-50);

	//牙齿 第二根直线（使用Wu反走样算法）
	CPoint wuline[2];
	wuline[0].x = -12;
	wuline[0].y = -25;
	wuline[1].x = -15;
	wuline[1].y = -50;
	Wuline(pDC,wuline[0],wuline[1]);
    
	//牙齿 第三根直线（使用DDA算法）
	CPoint dline[2];
	dline[0].x = 0;
	dline[0].y = -25;
	dline[1].x = 2;
	dline[1].y = -50;
	RLine(pDC,dline[0],dline[1]);

	//牙齿 第四根直线（使用Bresenham算法）
	CPoint bline[2];
	bline[0].x = 17;
	bline[0].y = -25;
	bline[1].x = 15;
	bline[1].y = -50;
	BLine(pDC,bline[1],bline[0]);


	/*for (int tx = -30 ; tx<=30 ; tx+=15){
		pDC->MoveTo(tx,-25);
		pDC->LineTo(tx,-50);
	}*/

	
	

	//锤尖A（三角形/多边形 线种子填充算法）
	CPen Pen3; //自定义一支笔（线的颜色）
	Pen3.CreatePen(PS_SOLID,5,RGB(238,119,0));
	pOldPen = pDC->SelectObject(&Pen3);
	CPoint cuijianA[3];
	cuijianA[0].x =-120; cuijianA[0].y =70; 
	cuijianA[1].x=-120; cuijianA[1].y =-55;
	cuijianA[2].x =-200; cuijianA[2].y =8;
	QFill *dd = new QFill();
	dd->DrawPolygon(pDC,cuijianA,3);
	CPoint seed0(-180, 8);
	COLORREF SeedClr0 = RGB(244,250,56);
	COLORREF BoundaryClr0 = RGB(238,119,0);


	//锤尖B（三角形/多边形 线种子填充算法）
	CPoint cuijianB[3];
	cuijianB[0].x =-cuijianA[0].x; cuijianB[0].y =70; 
	cuijianB[1].x=-cuijianA[1].x; cuijianB[1].y =-55;
	cuijianB[2].x =-cuijianA[2].x; cuijianB[2].y =8;
	QFill *dd1 = new QFill();
	dd1->DrawPolygon(pDC,cuijianB,3);
	CPoint seed1(180, 0);
	COLORREF SeedClr1 = RGB(244,250,56);
	COLORREF BoundaryClr1 = RGB(238,119,0);
	pDC->SelectObject(pOldPen);





	//锤柄（多边形）
	CPoint cuibing[4];
	cuibing[0].x = 45; cuibing[0].y =-75; 
	cuibing[1].x= -45; cuibing[1].y =-75;
	cuibing[2].x = -45; cuibing[2].y =-300;
	cuibing[3].x = 45; cuibing[3].y =-300;
	/*for (int i = 0 ; i < 3; i++){
		Wuline(pDC,cuibing[i],cuibing[i+1]);
	}*/
	CFill *cc = new CFill();
	cc->setRGB(101,140,161);
	cc->DrawFram(pDC,cuibing,4);
	cc->DrawPolygon(pDC,cuibing,4);
	COLORREF SeedClr2 = RGB(73,97,107);
	COLORREF BoundaryClr2 = RGB(101,140,161);
	

	pDC->SelectObject(pOldPen);

		CFont font0;
	font0.CreateFont(30, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY, VARIABLE_PITCH|FF_ROMAN, "黑体");
	//将字体选进DC中
	pOldFont = pDC->SelectObject(&font0);
	//字体颜色
	COLORREF textColor1 = RGB(235,235,235);
	pDC->SetTextColor(textColor1);
	QFill *dd4 = new QFill();
	CPoint seeda(200, -100);
	CPoint seedb(200, -170);
	CPoint seedc(185, -90);
	//按钮_右
	BresenhamCircle(pDC, 200, -180, 25, 0, RGB(0,0,0));
	//按钮_左
	BresenhamCircle(pDC, 200, -110, 25, 0, RGB(0,0,0));
	Bresenham2Circle(pDC, 200, -140, 50, 100, RGB(0,0,0));
	//线种子填充算法填充颜色
	dd4->CharFill(pDC,seedc,RGB(127,127,127),RGB(0,0,0));
	dd4->CharFill(pDC,seeda,RGB(192,192,192),RGB(0,0,0));
	dd4->CharFill(pDC,seedb,RGB(192,192,192),RGB(0,0,0));
	//设置字体背景透明
	pDC->SetBkMode(TRANSPARENT);
	//按钮文字
	pDC->TextOut(185,-90,"左");
	pDC->TextOut(185,-160,"右");
	
	//dd4->CharFill(pDC,seedc,RGB(255,0,0),RGB(0,0,0));
	pDC->SelectObject(pOldFont);
	
	cc->FillPolygon(pDC,cuibing,4,BoundaryClr2,SeedClr2);
	noseqf->FillPolygon(pDC,seed,SeedClr,BoundaryClr);
	dd->CharFill(pDC,seed0,SeedClr0,BoundaryClr0);
	dd1->CharFill(pDC,seed1,SeedClr1,BoundaryClr1); //线种子
	//dd->FillPolygon(pDC, seed, SeedClr, BoundaryClr); 八领域
	

	int sign = 0;
	for (int i = 0 ; i < 2 ; i++){
		QFill *dd2 = new QFill();
		QFill *dd3 = new QFill();
		if (sign==0){
			COLORREF Clr = RGB(237,28,36);
			dd2->FillPolygon(pDC,seed0,Clr,BoundaryClr1);
			dd3->FillPolygon(pDC,seed1,Clr,BoundaryClr1);
			sign=1;
		}else{
			COLORREF Clr = RGB(0,255,64);
			dd2->FillPolygon(pDC,seed0,Clr,BoundaryClr1);
			dd3->FillPolygon(pDC,seed1,Clr,BoundaryClr1);
			sign=0;
		}
		
	}


	


}

/////////////////////////////////////////////////////////////////////////////
// CTestView printing

BOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CTestView diagnostics

#ifdef _DEBUG
void CTestView::AssertValid() const
{
	CView::AssertValid();
}

void CTestView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTestDoc* CTestView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc)));
	return (CTestDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTestView message handlers

/*
   WuLine 反走样直线扫描算法
*/
void CTestView::Wuline(CDC *pDC,CPoint p0, CPoint p1)
{
    /*CRect rect;
    GetClientRect(&rect);
    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetWindowExt(rect.Width(), rect.Height());
    pDC->SetViewportExt(rect.Width(), -rect.Height());
    pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
    rect.OffsetRect(-rect.Width()/2, -rect.Height()/2);*/
	CPoint p, temp;
    int dx=p1.x-p0.x;
    int dy=p1.y-p0.y;
    double k=(dy*1.00)/(dx*1.00);//计算斜率
 
    if(dx==0)//垂线
    {
        if(dy<0)//起点在上方，调换
        {
            temp=p0;
            p0=p1;
            p1=temp;
        }
        for(p=p0; p.y<p1.y; p.y++)//主移动方向->y,不包括p1
        {
            pDC->SetPixelV(p.x, p.y, RGB(0,0,0));
        }
    }
 
    else
    {
        double e=0.00;//增量
 
        if(k>=0 && k<=1)
        {
            if(dx<0)//p1在左侧，调换
            {
                temp=p0;
                p0=p1;
                p1=temp;
            }//p0在左下
 
            for(p=p0; p.x<p1.x; p.x++)//主移动方向->x,不包括p1
            {
                pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
                pDC->SetPixelV(p.x, p.y+1, RGB((1-e)*255, (1-e)*255, (1-e)*255));//不同亮度值
                e+=k;
 
                if(e>=1.0)
                {
                    p.y++;
                    e-=1;
                }
            }
            /*p0.x+=10;
            p1.x+=10;
            pDC->MoveTo(p0);
            pDC->LineTo(p1);*/
        }
        else if(k>1)
        {
            if(dy<0)//p1在左侧，调换
            {
                temp=p0;
                p0=p1;
                p1=temp;
            }//p0在下方
 
            for(p=p0; p.y<p1.y; p.y++)//主移动方向->y,不包括p1
            {
                pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
                pDC->SetPixelV(p.x+1, p.y, RGB((1-e)*255, (1-e)*255, (1-e)*255));
                e+=1.00/(k*1.00);
 
                if(e>=1.0)
                {
                    p.x++;
                    e-=1;
                }
            }
        }
        
        else if(k>=-1 && k<0)
        {
            e=0.00;
            if(dx<0)//p1在左上，调换
            {
                temp=p0;
                p0=p1;
                p1=temp;
            }//p0在左上
            
            for(p=p0; p.x<p1.x; p.x++)//主移动方向->x,不包括p1
            {
                pDC->SetPixelV(p.x, p.y, RGB(-1*e*255, -1*e*255, -1*e*255));
                pDC->SetPixelV(p.x, p.y-1, RGB((1+e)*255, (1+e)*255, (1+e)*255));//这里e是负数！！！
                e+=k;
 
                if(e<=-1.0)
                {
                    p.y--;
                    e+=1.0;
                }
            }
        }
 
        else if(k<-1)
        {
            if(dy>0)//p1在上方，调换
            {
                temp=p0;
                p0=p1;
                p1=temp;
            }//p0在上
            for(p=p0; p.y>p1.y; p.y--)//主移动方向->y,不包括p1
            {
                pDC->SetPixelV(p.x, p.y, RGB(e*255, e*255, e*255));
                pDC->SetPixelV(p.x+1, p.y, RGB((1-e)*255, (1-e)*255, (1-e)*255));
                e+=-1.0/(k*1.0);
 
                if(e>=1.0)
                {
                    p.x++;
                    e-=1;
                }
            }
        }
 
    }
}
/*
	DDA算法自定义RLine函数绘制任意斜率的直线
  */
void CTestView::RLine(CDC *pDC, CPoint p0, CPoint p1)
{
	int dx = abs(p1.x) - abs(p0.x);
	int dy = abs(p1.y) - abs(p0.y);
	int dxs = abs(p0.y)-abs(p1.y);
	int epsl;
	if(abs(dx) > abs(dy)){
		epsl = dx;
	}
	else {
		epsl = dy;
	}
	double incrX = (double)dx/(double)epsl;
	double incrY = (double)dy/(double)epsl;
	double x = (double)p0.x;
	double y = (double)p0.y;
	for (int i = 0;i<=epsl;i++){
		pDC->SetPixelV(Round(x),Round(y)+dxs,RGB(0,0,0));
		x+=incrX;
		y+=incrY;
	}
}
/*
	DDA算法	 
*/
void CTestView::DLine(CDC *pDC, CPoint p0, CPoint p1)
{
	/*计算直线的斜率K*/
	int dx=p1.x-p0.x;//计算直线x方向的位移
	int dy=p1.y-p0.y;//计算直线y方向的位移
	//计算斜率k
	double k =(double)dy/(double)dx;
	//输出斜率k
	CString str;
	str.Format ("k=%f", k);
	pDC->TextOut(120, 120, str);
	if (dx>dy){
		//x方向是主位移方向,y=y+k
		double y = p0.y;
		//按主位移方向x=x+1,y=y+k,循环扫描转换输出
		for (int x= p0.x;x<p1.x;x++){
			pDC->SetPixelV(x, Round(y), RGB(0,0,0));
			y+=k;
		}
	}else{
		//y方向是主位移方向,x=x+1/k
		double x = p0.x;
		//按主位移方向y=y+1,x=x+1/k,循环扫描转换输出
		for(int y=p0.y;y<p1.y;y++){
			pDC->SetPixelV(Round(x),y,RGB(0,0,0));
			x= x+1/k;
		}
	}
}
/*
	自定义中点Bresenham算法函数绘制任意斜率直线
*/
void CTestView::BLine(CDC *pDC, CPoint p0, CPoint p1)
{
	CPoint t,p;//定义中间变量,用于直线起点的确定
	if((p0.x-p1.x)==0)//绘制垂线
	{
		if(p.y>p1.y)//交换顶点,使得起始点低于终点
		{
			t=p0;p0=p1;p1=t;
		}
		if (p0.y<p1.y){
			for (p=p0; p.y<p1.y;p.y++){
				pDC->SetPixelV(p.x,p.y,RGB(0,0,0));
			}
		}else{
			for (p=p1; p.y<p0.y;p.y++){
				pDC->SetPixelV(p.x,p.y,RGB(0,0,0));
			}
		}
		
	}else{
		double k,d;
		k=(double)(p1.y-p0.y)/(double)(p1.x-p0.x);//计算斜率K
		if(k>1)	//绘制k>1
		{
			if(p0.y>p1.y)//交换顶点,使得起始点低于终点
			{
				t=p0;p0=p1; p1=t;
			}

			d=1-0.5*k;//计算d的初始值
			//Y方向循环输出组成直线的像素点
			for (p=p0;p.y<p1.y;p.y++)
			{
				//绘制当前像素点
				pDC->SetPixelV(p. x, p. y, RGB(0,0,0));
				//判断中点的位置
				if(d>=0)
				{
					p.x++;//X坐标加1
					d+=1-k;//计算d的增量
				}
				else
					d+=1;//计算d的增量
			}
		}
		if(0<=k&&k<=1)	//绘制0<=k<=1
		{
			if(p0.x>p1.x) //交换顶点,使得起始点低于终点
			{
				t=p0;p0=p1;p1=t;
			}
			d=0.5-k;    //计算d的初始值
			//X方向循环输出组成直线的像素点
			for (p=p0; p.x<p1.x;p.x++)
			{	
				//绘制当前像素点
				pDC->SetPixelV(p.x,p. y, RGB(0,0,0));

				//判断中点的位置
				if(d<0)
				{
					p.y++;
					d+=1-k;
				}else
					d-=k;
			}
		}
		if(k>=-1&&k<0)//绘制-1<=k<0
		{
			if(p0.x>p1.x)//交换顶点,使得起始点低于终点
			{
				t=p0; p0=p1; p1=t;
			}
			d=0.5-k;		//计算d的初始值
			//X方向循环输出组成直线的像素点
			for(p=p0; p.x<p1.x;p.x++)
			{
				//绘制当前像素点
				pDC->SetPixelV(p.x, p.y, RGB(0, 0, 0));
				//判断中点的位置
				if(d>0)
				{
					p.y--;	//Y坐标减1
					d-=1+k;	//计算d的增量
				}
				else
					d-=k;	//计算d的增量
			}
		}
		if(k<-1)   //绘制k<-1
		{
			if(p0.y<p1.y)
			{
				t=p0; p0=p1; p1=t;
			}
			d=-1-0.5*k;//计算d的初始值
			//Y方向循环输出组成直线的像素点
			for(p=p0; p.y>p1.y; p.y--)
			{
				pDC->SetPixelV(p.x, p.y, RGB(0,0,0));
				if(d<0)
				{
					p.x++;		//X坐标加1
					d-=1+k;		//计算d的增量
				}
				else
					d-=1;		//计算d的增量
			}
		}
	}
}


// 八对称性画圆函数
void CTestView::CirclePoint(CDC *pDC,int xc, int yc,int x,int y,COLORREF color)
{
	pDC->SetPixelV( xc + x, yc + y, color);
    pDC->SetPixelV( xc - x, yc + y, color);
    pDC->SetPixelV( xc + x, yc - y, color);
    pDC->SetPixelV( xc - x, yc - y, color);
    pDC->SetPixelV( xc + y, yc + x, color);
    pDC->SetPixelV( xc - y, yc + x, color);
    pDC->SetPixelV( xc + y, yc - x, color);
    pDC->SetPixelV( xc - y, yc - x, color);
}


//Bresenham 画圆函数 
void CTestView::BresenhamCircle(CDC *pDC,int xc, int yc, int r, int fill, COLORREF color)
{
	// (xc, yc) 为圆心，r 为半径
    // fill 为是否填充
    // color 为颜色值
 
    int x = 0, y = r, yi, d;
    d = 3 - 2 * r;
 
    if (fill) {
        // 如果填充（画实心圆）
        while (x <= y) {
            for (yi = x; yi <= y; yi ++)
                CirclePoint(pDC, xc, yc, x, yi, color);
 
            if (d < 0) {
                d = d + 4 * x + 6;
            } else {
                d = d + 4 * (x - y) + 10;
                y --;
            }
            x++;
        }
    } else {
        // 如果不填充（画空心圆）
        while (x <= y) {
            CirclePoint(pDC, xc, yc, x, y, color);
 
            if (d < 0) {
                d = d + 4 * x + 6;
            } else {
                d = d + 4 * (x - y) + 10;
                y --;
            }
            x ++;
        }
    }

}

//Bresenham 画椭圆函数 圆心ox，圆心oy，横长a，纵长b，颜色color
void CTestView::Bresenham2Circle(CDC *pDC, int ox, int oy, int a, int b, COLORREF color)
{
	float d = b*b + a*a*(-b + 0.25);
	int x = 0, y = b, fx = a*a / sqrt((float)a*a + b*b);
	while (x != fx)
	{
		//计算边
		if (d < 0)
			d += b*b*(2 * x + 3);
		else
		{
			--y;
			d += b*b*(2 * x + 3) + a*a*(-2 * y + 2);
		}
		++x;
		//光栅、四分法（下同）
		pDC->SetPixel(ox + x, oy + y, color);
		pDC->SetPixel(ox - x, oy + y, color);
		pDC->SetPixel(ox + x, oy - y, color);
		pDC->SetPixel(ox - x, oy - y, color);
	}
	//中点改为(x+0.5,y-1)所以d = 
	d = b*b*(x + 0.5)*(x + 0.5) + a*a*(y - 1)*(y - 1) - a*a*b*b;
	while (y > 0)
	{
		if (d < 0)
		{
			++x;
			d += b*b*(2 * x + 2) + a*a*(-2 * y + 3);
		}
		else
			d += a*a*(-2 * y + 3);
		--y;
		//光栅、四分法
		pDC->SetPixel(ox + x, oy + y, color);
		pDC->SetPixel(ox - x, oy + y, color);
		pDC->SetPixel(ox + x, oy - y, color);
		pDC->SetPixel(ox - x, oy - y, color);
	}
}